home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1999 May: Tool Chest / Developer CD Series Tool Chest (Apple Computer)(May 1999).iso / Tool Chest / Devices / CD-ROM / iso9660 / Srcs / BuildISO.c next >
Encoding:
C/C++ Source or Header  |  1995-09-28  |  18.4 KB  |  723 lines  |  [TEXT/MPS ]

  1. #include <stdio.h>
  2. #include <ctype.h>
  3. #include <string.h>
  4. #include <Files.h>
  5. #include <OSUtils.h>
  6. #include <Memory.h>
  7. #include <Errors.h>
  8. #include <strings.h>
  9.  
  10. /************************************************************************
  11.  *
  12.  *    © Copyright 1988, 1990, 1994 Apple Computer, Inc.  All rights reserved.
  13.  *
  14.  *  Program:        BuildISO
  15.  *
  16.  *  Purpose:        build an ISO 9660 floppy
  17.  *
  18.  *  Description:    Try to build a ISO 9660 floppy disc, interactively.
  19.  *                    Currently only builds the Primary Volume Descriptor
  20.  *                    and puts files at the root level.  Does not do
  21.  *                    subdirectories.
  22.  *
  23.  *  Revision History:
  24.  *    1 July 88    Original Version for the Macintosh by Brian Bechtel,
  25.  *                Apple Computer, Inc.
  26.  *    April 90    Modified for d e v e l o p and Think C 4.0
  27.  *    January 94    Converted to Universal Headers.  Fixed a bug reported
  28.  *                by Hans-Martin Mosner (hmm@heeg.de) which prevented
  29.  *                Apple extensions from working correctly.
  30.  *
  31.  ************************************************************************/
  32.  
  33. #include "HighSierra.h"
  34. #include "BuildISO.h"
  35.  
  36. #define    FLOPPY_SIZE    0x186        /* size in 2k blocks of a 800k floppy */
  37.  
  38. #include "BuildISO.proto.h"
  39. #include "ErrorMsg.proto.h"
  40. #include "i_o.proto.h"
  41. #include "Support.proto.h"
  42. #include "MyDialog.proto.h"
  43.  
  44. Str255            nullStr = "\p";
  45. Str255            rootName = "\p\000";
  46. Str255            parentName = "\p\001";
  47.  
  48. /************************************************************************
  49.  *
  50.  *  Function:        CreatePVD
  51.  *
  52.  *  Purpose:        create the contents of the Primary Volume Descriptor.
  53.  *
  54.  *  Returns:        void
  55.  *
  56.  *  Side Effects:    adds to the output file.
  57.  *
  58.  *  Description:    go through all the primary volume descriptor, showing
  59.  *                    each field in all it's glory.  We don't bother showing
  60.  *                    the extra blanks at the end of each string field.
  61.  *
  62.  *
  63.  ************************************************************************/
  64.  
  65. OSErr
  66. CreatePVD(short referenceNumber)
  67. {
  68.     PVD        p;
  69.     OSErr    result;
  70.     long    offset;
  71.     char    volID[33];
  72.     Boolean    goOn;
  73.     
  74.     ClearOut((char *)&p, sizeof(p));
  75.     p.VDType = 1;
  76.     p.VSStdId[0] = 'C';
  77.     p.VSStdId[1] = 'D';
  78.     p.VSStdId[2] = '0';
  79.     p.VSStdId[3] = '0';
  80.     p.VSStdId[4] = '1';
  81.     p.VSStdVersion = 1;
  82.     CharCopy(p.systemIdentifier, "Apple Computer, Inc., Type:0001", sizeof(p.systemIdentifier));
  83.  
  84.     goOn = AskForString((char *)"\pWhat do you want to call this volume? (32 characters or less)", volID);
  85.     if (goOn == false)
  86.         return -1;
  87.  
  88.     NormalizeVolumeName(volID);
  89.     CharCopy(p.volumeIdentifier, volID, sizeof(p.volumeIdentifier));
  90.  
  91.  
  92.     p.lsbVolumeSpaceSize = NormalizeLong((long)FLOPPY_SIZE);
  93.     p.msbVolumeSpaceSize = (long)FLOPPY_SIZE;
  94.     p.lsbVolumeSetSize = NormalizeWord(FLOPPY_SIZE);
  95.     p.msbVolumeSetSize = FLOPPY_SIZE;
  96.     p.lsbVolumeSetSequenceNumber = NormalizeWord(1);
  97.     p.msbVolumeSetSequenceNumber = 1;
  98.     
  99.     p.lsbLogicalBlockSize = NormalizeWord(CDBLKSIZE);
  100.     p.msbLogicalBlockSize = CDBLKSIZE;
  101.                 
  102.  
  103.     p.lsbPathTableSize = NormalizeLong(PATHTBLSIZE);
  104.     p.msbPathTableSize = PATHTBLSIZE;
  105.     p.lsbPathTable1 = NormalizeLong(LSBPATH);
  106.     p.msbPathTable1 = MSBPATH;
  107.     
  108.     p.lsbPathTable2 = 0L;
  109.     p.msbPathTable2 = 0L;
  110.     
  111.     /* Exercise for reader: get the time via GetTime() and convert
  112.     ** to string of the format shown below for these strange dates.
  113.     ** Use that date and time to fill the various volume date fields.
  114.     ** The date shown is my daughter's birth date and time...
  115.     */
  116.     CharCopy(p.volumeCreation, "19870914060100000", sizeof(p.volumeCreation));
  117.     CharCopy(p.volumeModification, "19870914060100000", sizeof(p.volumeModification));
  118.     CharCopy(p.volumeExpiration, "00000000000000000", sizeof(p.volumeExpiration));
  119.     CharCopy(p.volumeEffective, "19870914060100000", sizeof(p.volumeEffective));
  120.  
  121.     p.FileStructureStandardVersion = 1;
  122.     
  123.     SpaceOut(p.volumeSetIdentifier, sizeof(p.volumeSetIdentifier));
  124.     SpaceOut(p.publisherIdentifier, sizeof(p.publisherIdentifier));
  125.     SpaceOut(p.dataPreparerIdentifier, sizeof(p.dataPreparerIdentifier));
  126.     SpaceOut(p.applicationIdentifier, sizeof(p.applicationIdentifier));
  127.     SpaceOut(p.copyrightFileIdentifier, sizeof(p.copyrightFileIdentifier));
  128.     SpaceOut(p.abstractFileIdentifier, sizeof(p.abstractFileIdentifier));
  129.     SpaceOut(p.bibliographicFileIdentifier, sizeof(p.bibliographicFileIdentifier));
  130.  
  131.     CreateDirRcd((DirRcd *)&p.rootDirectoryRecord, rootName, 
  132.         DIRECTORY, CDBLKSIZE, (short) directoryBit, 0L, 0L, 0);
  133.     
  134.     p.Reserved1 = 0;
  135.     ClearOut(p.Reserved2, sizeof(p.Reserved2));
  136.     ClearOut(p.Reserved3, sizeof(p.Reserved3));
  137.     p.Reserved4 = 0;
  138.  
  139. #ifdef VERBOSE    /* if I want to verify what I've done */
  140.     DumpPVD(&p);
  141. #endif
  142.     offset = (long) HSVOLSTART * (long) CDBLKSIZE;
  143.     result = isoWrite(referenceNumber, (Ptr)&p, (long) sizeof(p), (long)offset);
  144.     if (result != noErr)
  145.         ErrorMsg("CreatePVD: isoWrite() returned %d", result);
  146.     else
  147.         ErrorMsg("volume descriptors successfully created.");
  148.     return result;
  149. }
  150.  
  151.  
  152. /************************************************************************
  153.  *
  154.  *  Function:        CreateVDT
  155.  *
  156.  *  Purpose:        create the contents of the Volume Descriptor Terminator
  157.  *
  158.  *  Returns:        void
  159.  *
  160.  *  Side Effects:    adds to the output file.
  161.  *
  162.  *  Description:    Build a simple VDT, fill it in, and write it out to
  163.  *                    a famous place.
  164.  *
  165.  *
  166.  ************************************************************************/
  167.  
  168. OSErr
  169. CreateVDT(short referenceNumber)
  170. {
  171.     PVD        p;
  172.     OSErr    result;
  173.     long    offset;
  174.     
  175.     ClearOut((char *)&p, sizeof(p));
  176.     p.VDType = 255;
  177.     p.VSStdId[0] = 'C';
  178.     p.VSStdId[1] = 'D';
  179.     p.VSStdId[2] = '0';
  180.     p.VSStdId[3] = '0';
  181.     p.VSStdId[4] = '1';
  182.     p.VSStdVersion = 1;
  183.     offset = (long) HSTERMSTART * (long) CDBLKSIZE;
  184.     result = isoWrite(referenceNumber, (Ptr)&p, (long) sizeof(p), (long)offset);
  185.     if (result != noErr)
  186.         ErrorMsg("CreateVDT: isoWrite() returned %d", result);
  187.     return result;
  188. }
  189.  
  190.  
  191.  
  192.  
  193. /************************************************************************
  194.  *
  195.  *  Function:        CreatePathTable
  196.  *
  197.  *  Purpose:        create path tables
  198.  *
  199.  *  Returns:        nothing
  200.  *
  201.  *  Side Effects:    writes lsb path table and msb path table
  202.  *
  203.  *  Description:    We'll assume just the root.  Dump out the path
  204.  *                    path table in both formats.  We'll put the
  205.  *                    path table in famous spots.
  206.  *
  207.  ************************************************************************/
  208. OSErr
  209. CreatePathTable(short referenceNumber)
  210. {
  211.     char    buffer[CDBLKSIZE];
  212.     PathTableRecordPtr    d;
  213.     long    offset;
  214.     OSErr    result;
  215.     
  216.     ClearOut(buffer, sizeof(buffer));
  217.     d = (PathTableRecordPtr) &buffer[0];
  218.     
  219.     d->len_di = 1;
  220.     d->XARlength = 0;
  221.     d->dirLocation = NormalizeLong(DIRECTORY);
  222.     d->parentDN = 0;
  223.     
  224.     offset = LSBPATH * (long) CDBLKSIZE;
  225.     result = isoWrite(referenceNumber, buffer, (long) CDBLKSIZE, offset);
  226.     if (result != noErr)
  227.         ErrorMsg("CreatePathTable: isoWrite() returned %d", result);
  228.     
  229.     d->len_di = 1;
  230.     d->dirLocation = DIRECTORY;
  231.     d->parentDN = 0;
  232.     
  233.     offset = MSBPATH * (long) CDBLKSIZE;
  234.     result = isoWrite(referenceNumber, buffer, (long) CDBLKSIZE, offset);
  235.     if (result != noErr)
  236.         ErrorMsg("CreatePathTable: isoWrite() returned %d", result);
  237.     return result;
  238. }
  239.  
  240.  
  241. /************************************************************************
  242.  *
  243.  *  Function:    CreateDirRcd
  244.  *
  245.  *  Purpose:    Create a directory record for a file
  246.  *
  247.  *  Returns:    none
  248.  *
  249.  *  Side Effects:    fills *d with directory information.  We assume
  250.  *                    caller has allocated space for d.
  251.  *
  252.  *  Description:
  253.  *
  254.  ************************************************************************/
  255. void
  256. CreateDirRcd(DirRcd *d, StringPtr name, long start, long length, short flags, OSType fType, OSType fCreator, short finderFlags)
  257. {
  258.     Ptr        dPtr;
  259.     DateTimeRec    today;
  260.  
  261.     d->XARlength = 0;
  262.     d->lsbStart = NormalizeLong(start);
  263.     d->msbStart = start;
  264.     d->lsbDataLength = NormalizeLong(length);
  265.     d->msbDataLength = length;
  266.     d->fileFlags = flags;
  267.     if (finderFlags & fInvisible)
  268.         d->fileFlags |= existenceBit;
  269.     GetTime(&today);
  270.     d->year = today.year-1900;
  271.     d->month = today.month;
  272.     d->day = today.day;
  273.     d->hour = today.hour;
  274.     d->minute = today.minute;
  275.     d->second = today.second;
  276.     d->gmtOffset = 0;
  277.     d->interleaveSize = 0;
  278.     d->interleaveSkip = 0;
  279.     d->lsbVolSetSeqNum = NormalizeWord(1);
  280.     d->msbVolSetSeqNum = 1;
  281.     
  282.     d->len_fi = CreateISOName((char *)d->fi, name);
  283.  
  284.     d->len_dr = 32 + d->len_fi;
  285.     
  286.     AddAppleExtensions(d, fType, fCreator, finderFlags);
  287.     
  288.     if (d->len_dr & 1)    /* odd dirRcds need pad byte */
  289.     {
  290.         dPtr = (char *)d;
  291.         dPtr[d->len_dr] = '\000';
  292.         d->len_dr++;
  293.     }
  294. }
  295.  
  296.  
  297. /************************************************************************
  298.  *
  299.  *  Function:        AddOldAppleExtensions
  300.  *
  301.  *  Purpose:        optionally add apple extensions to ISO 9660
  302.  *
  303.  *  Returns:        void
  304.  *
  305.  *  Side Effects:    directory record may get extended.  Must have enough
  306.  *                    room in area pointed to by dirRcd for this to happen.
  307.  *
  308.  *  Description:    Check the fType.  If it's non-zero, add the information
  309.  *                    necessary for the Apple Extensions to ISO 9660.  Note
  310.  *                    that we can't just assign fType and fCreator, since
  311.  *                    longs are aligned within structures.
  312.  *
  313.  *                    This procedure adds the old, "BA" Apple extensions.
  314.  *
  315.  ************************************************************************/
  316. void
  317. AddOldAppleExtensions(DirRcd *dirRcd, OSType fType, OSType fCreator, short flags)
  318. {
  319.     OldAppleExtension    apple;
  320.     short            i;
  321.     short            j;
  322.     short            limit;
  323.     char            *aPtr;
  324.     Ptr                fPtr;
  325.     
  326.     if (fType != 0L)
  327.     {
  328.         apple.macFlag[0] = 'B';
  329.         apple.macFlag[1] = 'A';
  330.         apple.systemUseID = 06;
  331.         fPtr = (char *)&fType;
  332.         
  333.         for (i = 0; i < 4; i++)
  334.             apple.fileType[i] = fPtr[i];
  335.         fPtr = (char *)&fCreator;
  336.         
  337.         for (i = 0; i < 4; i++)
  338.             apple.fileCreator[i] = fPtr[i];
  339.         
  340.         apple.finderFlags[0] = (flags >> 8) & 0xFF;
  341.         apple.finderFlags[1] = flags & 0xFF;
  342.         
  343.         limit = sizeof(apple);
  344.         
  345.         aPtr = (char *)&apple;
  346.  
  347.         j = dirRcd->len_fi;
  348.         
  349.         if (!(j & 1))        /* 9401 bug fix BL°B */
  350.         {
  351.             dirRcd->fi[j] = 0;
  352.             j++;    /* there is a pad byte after odd length file names */
  353.         }
  354.         
  355.         for (i = 0; i <= limit; i++)
  356.             dirRcd->fi[i + j] = aPtr[i];
  357.         
  358.         dirRcd->len_dr += limit;
  359.     }
  360. }    
  361.  
  362.  
  363. /************************************************************************
  364.  *
  365.  *  Function:        AddAppleExtensions
  366.  *
  367.  *  Purpose:        optionally add apple extensions to ISO 9660
  368.  *
  369.  *  Returns:        void
  370.  *
  371.  *  Side Effects:    directory record may get extended.  Must have enough
  372.  *                    room in area pointed to by dirRcd for this to happen.
  373.  *
  374.  *  Description:    Check the fType.  If it's non-zero, add the information
  375.  *                    necessary for the Apple Extensions to ISO 9660.  Note
  376.  *                    that we can't just assign fType and fCreator, since
  377.  *                    longs are aligned within structures.
  378.  *
  379.  ************************************************************************/
  380. void
  381. AddAppleExtensions(DirRcd *dirRcd, OSType fType, OSType fCreator, short flags)
  382. {
  383.     AppleExtension    apple;
  384.     short            i;
  385.     short            j;
  386.     short            limit;
  387.     char            *aPtr;
  388.     Ptr                fPtr;
  389.     
  390.     if (fType != 0L)
  391.     {
  392.         apple.signature[0] = 'A';
  393.         apple.signature[1] = 'A';
  394.         apple.extensionLength = 0x0E;
  395.         apple.systemUseID = 02;
  396.         fPtr = (char *)&fType;
  397.         
  398.         for (i = 0; i < 4; i++)
  399.             apple.fileType[i] = fPtr[i];
  400.         fPtr = (char *)&fCreator;
  401.         
  402.         for (i = 0; i < 4; i++)
  403.             apple.fileCreator[i] = fPtr[i];
  404.         
  405.         apple.finderFlags[0] = (flags >> 8) & 0xFF;
  406.         apple.finderFlags[1] = flags & 0xFF;
  407.         
  408.         limit = sizeof(apple);
  409.         
  410.         aPtr = (char *)&apple;
  411.  
  412.         j = dirRcd->len_fi;
  413.         
  414.         if (!(j & 1))        /* 9401 bug fix BL°B */
  415.         {
  416.             dirRcd->fi[j] = 0;
  417.             j++;    /* there is a pad byte after odd length file names */
  418.         }
  419.         
  420.         for (i = 0; i <= limit; i++)
  421.             dirRcd->fi[i + j] = aPtr[i];
  422.         
  423.         dirRcd->len_dr += limit;
  424.     }
  425. }    
  426.  
  427.  
  428. /************************************************************************
  429.  *
  430.  *  Function:        CopyDirRcdToBuffer
  431.  *
  432.  *  Purpose:        copy directory record to buffer
  433.  *
  434.  *  Returns:        nothing
  435.  *
  436.  *  Side Effects:    buffer is filled a little bit more
  437.  *
  438.  *  Description:    copy a directory record to the buffer.
  439.  *
  440.  ************************************************************************/
  441. void
  442. CopyDirRcdToBuffer(DirRcd *d, char *b)
  443. {
  444.     char    *dPrime;
  445.     short    i;
  446.     
  447.     dPrime = (char *)d;
  448.     for (i = 0; i < d->len_dr; i++)
  449.         *b++ = *dPrime++;
  450. }
  451.  
  452. /************************************************************************
  453.  *
  454.  *  Function:        CopyRsrcFork
  455.  *
  456.  *  Purpose:        copy the resource fork of a file
  457.  *
  458.  *  Returns:        OSErr
  459.  *                        mostly noErr, but could be
  460.  *                        ioErr and the like if isoWrite complains.
  461.  *
  462.  *  Side Effects:    floppy gets new data written on it.
  463.  *
  464.  *  Description:    we have a starting location, "start", and a length.
  465.  *                    Allocate an appropriate buffer and read from the file
  466.  *                    specified by "name" and "vRefNum".  Write that information
  467.  *                    out to the floppy using our isoWrite call.
  468.  *
  469.  ************************************************************************/
  470. OSErr
  471. CopyRsrcFork(short referenceNumber, StringPtr name, short vRefNum, long start, long length)        /* how much to write */
  472. {
  473.     Ptr    rsrcBuf;
  474.     ParamBlockRec    pb;
  475.     Boolean        goOn;
  476.     OSErr        result;
  477.     long        physicalLength;
  478.     short        myRefNum;
  479.     
  480.     ClearOut((Ptr)&pb, sizeof(pb));
  481.     goOn = true;
  482.     physicalLength = ROUND_UP(length);
  483.     
  484.     rsrcBuf = NewPtrClear(physicalLength);
  485.     if (rsrcBuf == NULL)
  486.     {
  487.         ErrorMsg("Can't allocate %ld bytes for CopyRsrcFork()", length);
  488.         return mFulErr;    /* nothing to clean up */
  489.     }
  490.  
  491.     pb.ioParam.ioCompletion = NULL;
  492.     pb.ioParam.ioNamePtr = name;
  493.     pb.ioParam.ioVRefNum = vRefNum;
  494.     pb.ioParam.ioVersNum = 0;
  495.     pb.ioParam.ioPermssn = fsCurPerm;
  496.     pb.ioParam.ioMisc = NULL;
  497.     result = PBOpenRF(&pb, false);
  498.     if (result != noErr)
  499.     {
  500.         ErrorMsg("CopyRsrcFork: PBOpenRF returned %d", result);
  501.         ErrorMsg("vRefNum %d, name %P", vRefNum, name);
  502.         C2PStr((char *)name);
  503.         goOn = false;
  504.     }
  505.     
  506.     if (goOn)
  507.     {
  508.         myRefNum = pb.ioParam.ioRefNum;
  509.         result = FSRead(myRefNum, &length, rsrcBuf);
  510.         if (result != noErr)
  511.         {
  512.             ErrorMsg("CopyRsrcFork: FSRead returned %d", result);
  513.             goOn = false;
  514.         }
  515.     }
  516.     
  517.     if (goOn)
  518.     {
  519.         result = isoWrite(referenceNumber, rsrcBuf, physicalLength, start);
  520.  
  521.         if (result != noErr)
  522.         {
  523.             ErrorMsg("CopyRsrcFork: isoWrite returned %d", result);
  524.             goOn = false;
  525.         }
  526.     }
  527.         
  528.     PBClose(&pb, false);
  529.     DisposPtr(rsrcBuf);
  530.     return result;
  531. }
  532.  
  533.  
  534.  
  535. /************************************************************************
  536.  *
  537.  *  Function:        CopyDataFork
  538.  *
  539.  *  Purpose:        copy the resource fork of a file
  540.  *
  541.  *  Returns:        OSErr
  542.  *                        mostly noErr, but could be
  543.  *                        ioErr and the like if isoWrite complains.
  544.  *
  545.  *  Side Effects:    floppy gets new data written on it.
  546.  *
  547.  *  Description:    we have a starting location, "start", and a length.
  548.  *                    Allocate an appropriate buffer and read from the file
  549.  *                    specified by "name" and "vRefNum".  Write that information
  550.  *                    out to the floppy using our isoWrite call.
  551.  *
  552.  ************************************************************************/
  553. OSErr
  554. CopyDataFork(short referenceNumber, StringPtr name, short vRefNum, long start, long length)        /* how much to write */
  555. {
  556.     Ptr    dataBuf;
  557.     ParamBlockRec    pb;
  558.     Boolean        goOn;
  559.     OSErr        result;
  560.     long        physicalLength;
  561.     short        myRefNum;
  562.     
  563.     ClearOut((Ptr)&pb, sizeof(pb));
  564.     goOn = true;
  565.     physicalLength = ROUND_UP(length);
  566.     
  567.     dataBuf = NewPtrClear(physicalLength);
  568.     if (dataBuf == NULL)
  569.     {
  570.         ErrorMsg("Can't allocate %ld bytes for CopyDataFork()", length);
  571.         return mFulErr;    /* nothing to clean up */
  572.     }
  573.     
  574.     pb.ioParam.ioCompletion = NULL;
  575.     pb.ioParam.ioNamePtr = name;
  576.     pb.ioParam.ioVRefNum = vRefNum;
  577.     pb.ioParam.ioVersNum = 0;
  578.     pb.ioParam.ioPermssn = fsCurPerm;
  579.     pb.ioParam.ioMisc = NULL;
  580.     result = PBOpen(&pb, false);
  581.     if (result != noErr)
  582.     {
  583.         ErrorMsg("CopyDataFork: PBOpen returned %d", result);
  584.         ErrorMsg("vRefNum %d, name %P", vRefNum, name);
  585.         C2PStr((char *)name);
  586.         goOn = false;
  587.     }
  588.     
  589.     if (goOn)
  590.     {
  591.         myRefNum = pb.ioParam.ioRefNum;
  592.         result = FSRead(myRefNum, &length, dataBuf);
  593.         if (result != noErr)
  594.         {
  595.             ErrorMsg("CopyDataFork: FSRead returned %d", result);
  596.             goOn = false;
  597.         }
  598.     }
  599.     
  600.     if (goOn)
  601.     {
  602.         result = isoWrite(referenceNumber, dataBuf, physicalLength, start);
  603.  
  604.         if (result != noErr)
  605.         {
  606.             ErrorMsg("CopyDataFork: isoWrite returned %d", result);
  607.             goOn = false;
  608.         }
  609.     }
  610.     
  611.     PBClose(&pb, false);
  612.     DisposPtr(dataBuf);
  613.     return result;
  614. }
  615.  
  616. /************************************************************************
  617.  *
  618.  *  Function:        CreateFiles
  619.  *
  620.  *  Purpose:        create files in the root of a ISO floppy.
  621.  *    
  622.  *  Returns:        nothing
  623.  *
  624.  *  Side Effects:    floppy gets new data in famous root area
  625.  *
  626.  *  Description:    For each file, find the size of the two forks.
  627.  *                    Copy the resource fork first, then the data fork
  628.  *                    (associated files come before data files in ISO)
  629.  *
  630.  ************************************************************************/
  631. void
  632. CreateFiles(short referenceNumber)
  633. {
  634.     StringPtr    name;
  635.     short    vRefNum;
  636.     DirRcd    dirRcd;
  637.     long    start;        /* where we start putting data on the CD */
  638.     long    rsrcLength;
  639.     long    dataLength;
  640.     char    *b;
  641.     OSErr    result;
  642.     OSType    fType;
  643.     OSType    fCreator;
  644.     short    flags;
  645.     short    ISOFlags;
  646.     char    buffer[CDBLKSIZE];
  647.     
  648.     
  649.     ClearOut(buffer, sizeof(buffer));
  650.     b = &buffer[0];
  651.     name = (StringPtr)NewPtr(255);
  652.     if (name == NULL)
  653.     {
  654.         ErrorMsg("Can't allocate 255 bytes for a string.");
  655.         return;
  656.     }
  657.  
  658.     CreateDirRcd(&dirRcd, rootName, DIRECTORY, CDBLKSIZE, (short) directoryBit, 0L, 0L, 0);
  659.     CopyDirRcdToBuffer(&dirRcd, b);
  660.     b += dirRcd.len_dr;
  661.  
  662.     CreateDirRcd(&dirRcd, parentName, DIRECTORY, CDBLKSIZE, (short) directoryBit, 0L, 0L, 0);
  663.     CopyDirRcdToBuffer(&dirRcd, b);
  664.     b += dirRcd.len_dr;
  665.  
  666.     start = DATASTART * CDBLKSIZE;
  667.  
  668.     /* Keep asking for names, even if errors occur.  Most errors will be because
  669.      * The user tried to copy too big of a file to the floppy. 
  670.      */
  671.     while (HFSFile(name, &vRefNum) == true)
  672.     {
  673.         result = GetFileInfo(name, vRefNum, &rsrcLength, &dataLength, &fType, &fCreator, &flags);
  674.         if (result != noErr)
  675.             ErrorMsg("Can't get file information for %s", name);
  676.         else
  677.         {
  678.             ISOFlags = (flags & fInvisible) ? existenceBit : 0;
  679.     
  680.             if (rsrcLength != 0L)
  681.             {
  682.                 CreateDirRcd(&dirRcd, name, start/CDBLKSIZE, rsrcLength, ISOFlags | associatedBit,
  683.                     fType, fCreator, flags);
  684.     
  685.                 result = CopyRsrcFork(referenceNumber, name, vRefNum, start, rsrcLength);
  686.                 if (result == noErr)
  687.                 {
  688.                     CopyDirRcdToBuffer(&dirRcd, b);
  689.                     b += dirRcd.len_dr;
  690.                     start = ROUND_UP(start+rsrcLength);
  691.                 }
  692.                 else
  693.                     ErrorMsg("Failed to copy resource fork.");
  694.         
  695.             }
  696.     
  697.             if (result == noErr)
  698.             {
  699.                 CreateDirRcd(&dirRcd, name, start/CDBLKSIZE, dataLength, ISOFlags, 
  700.                     fType, fCreator, flags);
  701.         
  702.                 result = CopyDataFork(referenceNumber, name, vRefNum, start, dataLength);
  703.                 if (result == noErr)
  704.                 {
  705.                     CopyDirRcdToBuffer(&dirRcd, b);
  706.                     b += dirRcd.len_dr;
  707.                     start = ROUND_UP(start+dataLength);
  708.                 }
  709.                 else
  710.                     ErrorMsg("Failed to copy data fork.");
  711.         
  712.                 ClearOut((Ptr)name, 255);
  713.             }
  714.         }
  715.     }
  716.  
  717.     result = isoWrite(referenceNumber, (Ptr)buffer, (long)sizeof(buffer), (long) (DIRECTORY*CDBLKSIZE));
  718.     if (result != noErr)
  719.         ErrorMsg("CreateDataFiles: isoWrite of directory records returned %d", result);
  720.     DisposPtr((Ptr)name);
  721. }
  722.  
  723.